<?php

declare(strict_types=1);

namespace App\Job;

use _PHPStan_adbc35a1c\Nette\Neon\Exception;
use App\Model\Applet;
use App\Model\AppletPlayletRel;
use App\Model\Playlet;
use App\Model\PlayletEpisodes;
use GuzzleHttp\Client;
use Hyperf\AsyncQueue\Job;
use Psr\Log\LoggerInterface;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Logger\LoggerFactory;
class WxMediaJob extends Job
{

    public $ids;

    public $redis;
    protected LoggerInterface $logger;

    public static $getTokenUrl = "https://api.weixin.qq.com/cgi-bin/token";

    public static $pullUploadUrl = "https://api.weixin.qq.com/wxa/sec/vod/pullupload";
    public function __construct($ids)
    {
        $container = ApplicationContext::getContainer();
        $this->logger = $container->get(LoggerFactory::class)->get('log', 'wxvod');
        $this->ids = $ids;
    }

    public function handle()
    {

        $playletEpisodesIds = $this->ids;
        try {
            //开始上传
            $playletEpisodesData = PlayletEpisodes::query()->where('is_upload',2)->whereIn('id',$playletEpisodesIds)->get();
            if(!empty($playletEpisodesData)){
                $this->logger->info('获取对应的短剧的Ids');
                //获取对应的短剧的Ids
                $playletIds = PlayletEpisodes::query()->whereIn('id',$playletEpisodesIds)->pluck('playlet_id');

                if(!empty($playletIds)){
                    $this->logger->info('获取对应的短剧的数据');
                    $playletData =  Playlet::query()->whereIn('id',$playletIds)->select(['id','name'])->get();
                    $playletKeyVal = [];
                    if(!empty($playletData)){
                        $playletIds = array();
                        foreach ($playletData as $playletDatum){
                            $playletKeyVal[$playletDatum->id] = $playletDatum->name;
                            $playletIds[] = $playletDatum->id;
                        }
                        //查询关联表中的微信小程序ID
                        $this->logger->info('查询关联表中的微信小程序ID');
                        $appletPlayletRelData = AppletPlayletRel::query()->whereIn('playlet_id',$playletIds)->where(['applet_id' => 10000])->select(['playlet_id','applet_id'])->get();
                        if(!empty($appletPlayletRelData)){
                            $appletIds = array();
                            $appletPlayletKeyVal = array();
                            //遍历获取对应关系和微信小程序ID
                            foreach ($appletPlayletRelData as $appletPlayletRelDatum){

                                $appletPlayletKeyVal[$appletPlayletRelDatum->playlet_id][] = $appletPlayletRelDatum->applet_id;
                                $appletIds[] = $appletPlayletRelDatum->applet_id;

                            }
                            $appletIds = array_values(array_unique($appletIds));
                            //查询微信小程序的ID 获取appID 和密钥
                            $this->logger->info('查询微信小程序的ID 获取appID 和密钥');
                            $appletData = Applet::query()->whereIn('id',$appletIds)->where(['type' => 1])->select(['id','name','app_id','app_secret'])->get();
                            if(!empty($appletData)) {
                                $appletKeyVal = [];
                                foreach ($appletData as $appletDatum) {
                                    $appletKeyVal[$appletDatum->id] = $appletDatum;
                                }
                                $this->logger->info('开始遍历上传短剧剧集集数');
                                foreach ($playletEpisodesData as $playletEpisodes){
                                    $playlet_number_name = '第'.$playletEpisodes->playlet_number.'集';
                                    if(!empty($playletKeyVal[$playletEpisodes->playlet_id])){
                                        //短剧名称
                                        $playlet_name = $playletKeyVal[$playletEpisodes->playlet_id];
                                        //获取对应的微信小程序accessToken
                                        //获取这个短剧绑定的微信小程序
                                        $appletPlayletData = $appletPlayletKeyVal[$playletEpisodes->playlet_id];
                                        $appletInfo = array();
                                        foreach ($appletPlayletData as $appletPlayletDatum){
                                            if(!empty($appletKeyVal[$appletPlayletDatum])){
                                                $appletInfo = $appletKeyVal[$appletPlayletDatum];
                                                break;
                                            }
                                        }
                                        if(!empty($appletInfo)){
                                            $applet_name = $appletInfo->name;
                                            $this->logger->info('获取绑定此短剧的微信小程序token');
                                            $accessToken = $this->getWxAccessToken($appletInfo->id,$appletInfo->app_id,$appletInfo->app_secret);
                                            if(!empty($accessToken)){

                                                $this->logger->info('微信小程序：'.$applet_name.' 短剧：'.$playlet_name.'开始上传 集数'.$playlet_number_name);
                                                $task_id = $this->vodUpolad($accessToken,$playlet_name,$playlet_number_name,$playletEpisodes->play_url,$playletEpisodes->cover);
                                                if(!empty($task_id)){

                                                    $playletEpisodes->task_id = $task_id;
//                                                    $playletEpisodes->media_status = 1;
                                                    $playletEpisodes->save();
                                                }else{
                                                    $playletEpisodes->is_upload = 4;
                                                    $playletEpisodes->save();
                                                }
                                            }else{
                                                $this->logger->error('微信小程序:'.$applet_name.' 短剧:'.$playlet_name.' 没有对应的token');
                                            }

                                        }else{
                                            $this->logger->error('短剧:'.$playlet_name.' 没有任何绑定的微信小程序');
                                        }
                                    }else{
                                        $this->logger->error('集数ID:'.$playletEpisodes->id.' 没有对应短剧不存在');
                                    }
                                }
                            }else{
                                $this->logger->error('查询微信小程序的ID 获取appID 和密钥：没有对应的微信小程序数据');
                            }
                        }else{
                            $this->logger->error('查询关联表中的微信小程序ID：没有对应的短剧数据');
                        }
                    }else{
                        $this->logger->error('获取对应的短剧的数据：没有对应的短剧数据');
                    }
                }else{
                    $this->logger->error('获取对应的短剧的Ids失败：没有对应的短剧ID');
                }
            }else{
                $this->logger->info('没有数据需要上传');
            }
        }catch (\Exception $e){
            $this->logger->error('请求微信上传资质接口|错误：' . $e->getLine() . '|' . $e->getMessage());
        }
    }


    public function vodUpolad($accessToken,$playlet_name,$playlet_number_name,$media_url,$cover_url){

        $media_name = $playlet_name.'-'.$playlet_number_name;
        $params         = [
            "media_name"    => $media_name,
            "media_url"    => $media_url,
            "cover_url"     => $cover_url,
        ];
        $uploadUrl = self::$pullUploadUrl.'?access_token='.$accessToken;
        $this->logger->info('请求数据：'.PHP_EOL.var_export(['result' => $params], true));
        $this->logger->info('请求Url：'.$uploadUrl);
        //开始上传

        $uploadResult  = $this->request($params, $uploadUrl,'POST');
        if($uploadResult['errcode'] == 0){
            $this->logger->info('上传成功 返回数据：'.PHP_EOL.var_export(['result' => $uploadResult], true));
            $task_id = $uploadResult['task_id'];
            return $task_id;
        }else{
            $this->logger->error('上传失败 返回数据：'.PHP_EOL.var_export(['result' => $uploadResult], true));
        }
        return false;
    }


    public function getWxAccessToken($applet_id,$app_id,$app_secret){

        $container = ApplicationContext::getContainer();

        $redis = $container->get(\Hyperf\Redis\RedisFactory::class)->get('wx');

        $key = 'wx_access_token';
        $key .= $applet_id;
        $accessToken = $redis->get($key);
        if(empty($accessToken)){
            $params         = [
                'grant_type' => 'client_credential',
                'appid'    => $app_id,
                'secret'   => $app_secret
            ];
            //获取token
            $accessTokenInfo     = $this->request($params, self::$getTokenUrl,'GET');

            if (!empty($accessTokenInfo['access_token'])){
                $accessToken = $accessTokenInfo['access_token'];
                $redis->setex($key,7100,$accessToken);
            }else{
                $accessToken = "";
            }
        }
        return $accessToken;
    }


    /**
     * 传入数组进行HTTP POST请求
     */
    function request(array $params, string $url,string $method)
    {
        $client   = new Client([
            'timeout' => 3
        ]);
        $headers       =['Content-Type' => 'application/json;charset=utf-8', 'Accept' => 'application/json','Accept-Charset' => 'utf-8'];
        $requestParams = [
            'headers' => $headers,
        ];
        if ($method == 'GET') {
            $requestParams['query'] = $params;
        } else {
            $requestParams['body'] = json_encode($params,JSON_UNESCAPED_UNICODE);
        }
//        var_dump($requestParams);
        $response = $client->request($method,$url, $requestParams);
        if ($response->getStatusCode() !== 200) {
            return '';
        }
        $result   = $response->getBody()->getContents();
        $resultArr = json_decode($result,true);
        return $resultArr;

    }
}